package com.zzw.controller;

import com.zzw.service.AsyncTaskService;
import com.zzw.service.ThreadPoolTaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

@Controller
@RequestMapping("thread-pool")
public class ThreadPoolController {

    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolController.class);

    @Autowired
    private AsyncTaskService asyncTaskService;

    @Autowired
    private ThreadPoolTaskService threadPoolTaskService;

    /**
     * 跳转到线程池测试页面
     */
    @RequestMapping("/list")
    public String toThreadPoolTestPage() {
        return "threadpool/list";
    }

    /**
     * 测试@Async注解的异步方法
     */
    @GetMapping("/async-task")
    @ResponseBody
    public Map<String, Object> testAsyncTask() {
        logger.info("开始调用异步任务服务");

        // 调用无返回值的异步方法
        asyncTaskService.executeAsyncTask("异步任务1");
        asyncTaskService.executeAsyncTask("异步任务2");

        // 调用有返回值的异步方法
        CompletableFuture<String> future1 = asyncTaskService.executeAsyncTaskWithResult("带返回值的异步任务1");
        CompletableFuture<String> future2 = asyncTaskService.executeAsyncTaskWithResult("带返回值的异步任务2");

        // 合并多个CompletableFuture的结果
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);

        try {
            // 等待所有任务完成
            allFutures.get(5, TimeUnit.SECONDS);

            // 获取结果
            String result1 = future1.get();
            String result2 = future2.get();

            Map<String, Object> result = new HashMap<>();
            result.put("status", "success");
            result.put("message", "异步任务已提交");
            result.put("result1", result1);
            result.put("result2", result2);

            return result;
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            Thread.currentThread().interrupt();
            Map<String, Object> result = new HashMap<>();
            result.put("status", "error");
            result.put("message", "执行异步任务出错: " + e.getMessage());
            return result;
        }
    }

    /**
     * 测试直接使用ThreadPoolExecutor
     */
    @GetMapping("/thread-pool")
    @ResponseBody
    public Map<String, Object> testThreadPool() {
        logger.info("开始调用线程池服务");

        // 提交无返回值任务
        threadPoolTaskService.submitTask("Runnable任务1");
        threadPoolTaskService.submitTask("Runnable任务2");

        // 提交有返回值任务
        Future<String> future1 = threadPoolTaskService.submitTaskWithResult("Callable任务1");
        Future<String> future2 = threadPoolTaskService.submitTaskWithResult("Callable任务2");

        try {
            // 获取任务结果，设置超时时间
            String result1 = future1.get(3, TimeUnit.SECONDS);
            String result2 = future2.get(3, TimeUnit.SECONDS);

            Map<String, Object> result = new HashMap<>();
            result.put("status", "success");
            result.put("message", "线程池任务已提交");
            result.put("result1", result1);
            result.put("result2", result2);
            result.put("threadPoolInfo", threadPoolTaskService.getThreadPoolInfo());

            return result;
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            Thread.currentThread().interrupt();
            Map<String, Object> result = new HashMap<>();
            result.put("status", "error");
            result.put("message", "执行线程池任务出错: " + e.getMessage());
            return result;
        }
    }

    /**
     * 批量提交任务到线程池
     */
    @GetMapping("/batch-tasks")
    @ResponseBody
    public Map<String, Object> batchTasks(@RequestParam(defaultValue = "5") int count) {
        logger.info("开始批量提交{}个任务到线程池", count);

        List<Future<String>> futures = threadPoolTaskService.submitBatchTasks(count);

        try {
            // 等待所有结果，最多等待10秒
            List<String> results = futures.stream()
                    .map(future -> {
                        try {
                            return future.get(10, TimeUnit.SECONDS);
                        } catch (Exception e) {
                            return "任务执行失败: " + e.getMessage();
                        }
                    })
                    .collect(Collectors.toList());

            Map<String, Object> result = new HashMap<>();
            result.put("status", "success");
            result.put("message", count + "个批量任务已提交");
            result.put("results", results);
            result.put("threadPoolInfo", threadPoolTaskService.getThreadPoolInfo());

            return result;
        } catch (Exception e) {
            Map<String, Object> result = new HashMap<>();
            result.put("status", "error");
            result.put("message", "执行批量任务出错: " + e.getMessage());
            return result;
        }
    }

    /**
     * 获取线程池状态
     */
    @GetMapping("/status")
    @ResponseBody
    public Map<String, Object> getThreadPoolStatus() {
        String status = threadPoolTaskService.getThreadPoolInfo();

        Map<String, Object> result = new HashMap<>();
        result.put("status", "success");
        result.put("threadPoolInfo", status);

        return result;
    }
}
